Skip to content

Method: lambda$createReasoner$2(Reasoner, String, String)

1: /**
2: * Copyright (C) 2020 Czech Technical University in Prague
3: * <p>
4: * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public
5: * License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later
6: * version.
7: * <p>
8: * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
9: * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
10: * details. You should have received a copy of the GNU General Public License along with this program. If not, see
11: * <http://www.gnu.org/licenses/>.
12: */
13: package cz.cvut.kbss.ontodriver.jena.connector;
14:
15: import cz.cvut.kbss.ontodriver.config.DriverConfigParam;
16: import cz.cvut.kbss.ontodriver.config.DriverConfiguration;
17: import cz.cvut.kbss.ontodriver.jena.exception.ReasonerInitializationException;
18: import org.apache.jena.query.Dataset;
19: import org.apache.jena.query.DatasetFactory;
20: import org.apache.jena.rdf.model.InfModel;
21: import org.apache.jena.rdf.model.Model;
22: import org.apache.jena.rdf.model.ModelFactory;
23: import org.apache.jena.rdf.model.Property;
24: import org.apache.jena.reasoner.IllegalParameterException;
25: import org.apache.jena.reasoner.Reasoner;
26: import org.apache.jena.reasoner.ReasonerFactory;
27: import org.apache.jena.reasoner.ValidityReport;
28: import org.apache.jena.system.Txn;
29: import org.apache.jena.vocabulary.ReasonerVocabulary;
30:
31: import java.lang.reflect.InvocationTargetException;
32: import java.lang.reflect.Method;
33: import java.util.*;
34: import java.util.stream.Collectors;
35:
36: import static org.apache.jena.rdf.model.ResourceFactory.createProperty;
37:
38: class SnapshotStorageWithInference extends SnapshotStorage {
39:
40: /**
41: * Configuration parameters supported by at least one of the Jena reasoners. Used to pre-filter reasoner config.
42: */
43: private static final Set<String> SUPPORTED_CONFIG = new HashSet<>(Arrays.asList(
44: ReasonerVocabulary.PROPderivationLogging.getURI(),
45: ReasonerVocabulary.PROPenableCMPScan.getURI(),
46: ReasonerVocabulary.PROPenableFunctorFiltering.getURI(),
47: ReasonerVocabulary.PROPenableOWLTranslation.getURI(),
48: ReasonerVocabulary.PROPenableTGCCaching.getURI(),
49: ReasonerVocabulary.PROPruleMode.getURI(),
50: ReasonerVocabulary.PROPruleSet.getURI(),
51: ReasonerVocabulary.PROPsetRDFSLevel.getURI(),
52: ReasonerVocabulary.PROPtraceOn.getURI()
53: ));
54:
55: private final ReasonerFactory reasonerFactory;
56: private final Map<String, String> reasonerConfig;
57:
58: private final Map<String, InfModel> inferredGraphs = new HashMap<>();
59:
60: SnapshotStorageWithInference(DriverConfiguration configuration, Map<String, String> reasonerConfig) {
61: super(configuration);
62: this.reasonerFactory = initReasonerFactory(configuration);
63: this.reasonerConfig = reasonerConfig.entrySet().stream()
64: .filter(e -> SUPPORTED_CONFIG.contains(e.getKey()))
65: .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
66: this.dataset = DatasetFactory.createGeneral();
67: }
68:
69: private ReasonerFactory initReasonerFactory(DriverConfiguration configuration) {
70: final String factoryClass = configuration.getProperty(DriverConfigParam.REASONER_FACTORY_CLASS, "");
71: LOG.trace("Creating reasoner using reasoner factory class {}.", factoryClass);
72: try {
73: final Class<? extends ReasonerFactory> rfClass =
74: (Class<? extends ReasonerFactory>) Class.forName(factoryClass);
75: final Method instanceMethod = rfClass.getMethod("theInstance");
76: return (ReasonerFactory) instanceMethod.invoke(null);
77: } catch (ClassNotFoundException e) {
78: throw new ReasonerInitializationException("Reasoner factory class " + factoryClass + " not found.", e);
79: } catch (NoSuchMethodException e) {
80: throw new ReasonerInitializationException("Class " + factoryClass +
81: " is not a ReasonerFactory implementation or does not contain static 'theInstance' method.");
82: } catch (IllegalAccessException | InvocationTargetException e) {
83: throw new ReasonerInitializationException(
84: "Unable to instantiate Jena reasoner from factory " + factoryClass, e);
85: }
86: }
87:
88: @Override
89: void addCentralData(Dataset central) {
90: Txn.executeRead(central, () -> {
91: final Iterator<String> it = central.listNames();
92: InfModel clonedModel;
93: while (it.hasNext()) {
94: final String name = it.next();
95: clonedModel = cloneModel(central.getNamedModel(name));
96: inferredGraphs.put(name, clonedModel);
97: dataset.addNamedModel(name, clonedModel);
98: }
99: clonedModel = cloneModel(central.getDefaultModel());
100: inferredGraphs.put(null, clonedModel);
101: dataset.setDefaultModel(clonedModel);
102: });
103: }
104:
105: private InfModel cloneModel(Model model) {
106: return ModelFactory.createInfModel(createReasoner(), ModelFactory.createDefaultModel().add(model));
107: }
108:
109: @Override
110: public InfModel getDefaultGraph() {
111: return inferredGraphs.get(null);
112: }
113:
114: private Reasoner createReasoner() {
115: final Reasoner reasoner = reasonerFactory.create(null);
116: reasonerConfig.forEach((key, value) -> {
117: final Property prop = createProperty(key);
118: try {
119: reasoner.setParameter(prop, value);
120: } catch (IllegalParameterException ex) {
121: LOG.error("Failed to set property " + prop + " on reasoner.", ex);
122: }
123: });
124: return reasoner;
125: }
126:
127: Model getRawDefaultGraph() {
128: return inferredGraphs.containsKey(null) ? inferredGraphs.get(null).getRawModel() : dataset.getDefaultModel();
129: }
130:
131: @Override
132: public InfModel getNamedGraph(String context) {
133: return inferredGraphs.computeIfAbsent(context, c -> {
134: // If the context does not exist, we need to create it, so that the default Dataset behavior is preserved
135: final InfModel model = ModelFactory.createInfModel(createReasoner(), ModelFactory.createDefaultModel());
136: dataset.addNamedModel(context, model);
137: return model;
138: });
139: }
140:
141: Model getRawNamedGraph(String context) {
142: return inferredGraphs.containsKey(context) ? inferredGraphs.get(context).getRawModel() :
143: dataset.getNamedModel(context);
144: }
145:
146: ValidityReport checkConsistency(String context) {
147: return context != null ? getNamedGraph(context).validate() : getDefaultGraph().validate();
148: }
149: }